/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

import java.awt.*;
import java.util.*;
import java.text.*;
//import com.klg.jclass.chart.beans.*;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.event.*;
import com.borland.jbcl.layout.*;
import com.ibm.eou.swingchart.*;

/**
 * <p>A frequency chart frame in the standalone version</p>
 * @author Andriy Nikolov
 * @version 1.0
 */

public class FrequencyChartFrame extends JFrame {
  FrequencyChart chartData;
  TitledBorder titledBorder1;
  JPanel panelSettings = new JPanel();
  JPanel jPanelPreferences = new JPanel();
  VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
  JPanel jPanelButtons = new JPanel();
  GridLayout gridLayout1 = new GridLayout();
  JPanel jPanelStartEnd = new JPanel();
  JLabel jLabelFrom = new JLabel();
  JTextField jTextFieldFrom = new JTextField();
  JComboBox jComboBoxFromMonth = new JComboBox();
  JComboBox jComboBoxFromYear = new JComboBox();
  GridBagLayout gridBagLayout1 = new GridBagLayout();
  JLabel jLabelFromTo = new JLabel();
  JTextField jTextFieldTo = new JTextField();
  JComboBox jComboBoxToMonth = new JComboBox();
  JComboBox jComboBoxToYear = new JComboBox();
  JLabel jLabelInterval = new JLabel();
  JTextField jTextFieldInterval = new JTextField();
  JComboBox jComboBoxInterval = new JComboBox();
  JButton jButtonRefresh = new JButton();
  String[] months = {
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
  };
  String[] intervalTypes = {
    "Days",
    "Weeks",
    "Months",
    "Years"
  };
  String[] possibleYears;
  PlotChart frequencyChart = new PlotChart();

  public FrequencyChartFrame() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public FrequencyChartFrame(FrequencyChart data) {
    try {
      chartData = data;
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void setChartData(FrequencyChart data) {
    chartData = data;
  }

  public FrequencyChart getChartData() {
    return chartData;
  }

  private void jbInit() throws Exception {
    jComboBoxFromMonth = new JComboBox(months);
    jComboBoxToMonth = new JComboBox(months);
    jComboBoxInterval = new JComboBox(intervalTypes);
    possibleYears = getPossibleYears();
    jComboBoxFromYear = new JComboBox(possibleYears);
    jComboBoxToYear = new JComboBox(possibleYears);

    this.setSize(700, 500);
    this.setTitle("Message Frequency Chart");

    titledBorder1 = new TitledBorder("");
    panelSettings.setBorder(BorderFactory.createEtchedBorder());
    panelSettings.setLayout(gridLayout1);
    jPanelPreferences.setLayout(verticalFlowLayout1);
    jLabelFrom.setText("From");
    jTextFieldFrom.setText("1");

    jPanelStartEnd.setLayout(gridBagLayout1);
    jLabelFromTo.setText("To");

    jTextFieldTo.setText("1");

    jLabelInterval.setText("Interval");
    jTextFieldInterval.setText("1");
    jButtonRefresh.setText("Refresh");
    jButtonRefresh.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButtonRefresh_actionPerformed(e);
      }
    });
    frequencyChart.setBackground(Color.white);
    jPanelStartEnd.add(jLabelFrom,                      new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 6), 0, 0));
    jPanelStartEnd.add(jComboBoxFromMonth,                          new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    jPanelStartEnd.add(jComboBoxFromYear,                                        new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 7, 0));
    jPanelStartEnd.add(jTextFieldFrom,                                new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 15, 0));
    jPanelStartEnd.add(jLabelFromTo,                   new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    this.getContentPane().add(panelSettings,  BorderLayout.SOUTH);
    panelSettings.add(jPanelPreferences, null);
    jPanelPreferences.add(jPanelStartEnd, null);
    panelSettings.add(jPanelButtons, null);
    jPanelStartEnd.add(jTextFieldTo,            new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 15, 0));
    jPanelStartEnd.add(jComboBoxToMonth,               new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    jPanelStartEnd.add(jLabelInterval,          new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    jPanelStartEnd.add(jTextFieldInterval,     new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 15, 0));
    jPanelStartEnd.add(jComboBoxToYear,     new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 7, 0));
    jPanelStartEnd.add(jComboBoxInterval,  new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    jPanelButtons.add(jButtonRefresh, null);
    this.getContentPane().add(frequencyChart, BorderLayout.CENTER);

//    String dataString = getDataString();
  }

  void jButtonRefresh_actionPerformed(ActionEvent e) {
    String dataString;
    setChartData();
    chartData.refreshChart();
    dataString = getDataString();
    frequencyChart.setLabels(getLabels());
    frequencyChart.setValues(getValuesArray());
//    frequencyChart.setData(dataString);
  }

  private String[] getPossibleYears() {
    String[] years = null;
    int size, startYear;
    size = chartData.getMaximumYear()-chartData.getMinimumYear()+1;
    startYear = chartData.getMinimumYear();
    years = new String[size];
    for (int i = 0;i<size;i++) {
      years[i] = Integer.toString(startYear+i);
    }
    return years;
  }

  private void setChartData() {
    String sValue;
    int iValue;
    Integer tmp;
    Date curDate;
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setLenient(false);
    try {
      sValue = (String)jComboBoxFromYear.getSelectedItem();
      tmp = new Integer(sValue);
      iValue = tmp.intValue();
      calendar.set(Calendar.YEAR, iValue);
      iValue = jComboBoxFromMonth.getSelectedIndex();
      calendar.set(Calendar.MONTH, iValue);
      sValue = jTextFieldFrom.getText();
      tmp = new Integer(sValue);
      iValue = tmp.intValue();
      calendar.set(Calendar.DAY_OF_MONTH, iValue);
      curDate = calendar.getTime();
      chartData.setStartDate(curDate);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(this, "Start date is invalid");
    }
    try {
      sValue = (String)jComboBoxToYear.getSelectedItem();
      tmp = new Integer(sValue);
      iValue = tmp.intValue();
      calendar.set(Calendar.YEAR, iValue);
      iValue = jComboBoxToMonth.getSelectedIndex();
      calendar.set(Calendar.MONTH, iValue);
      sValue = jTextFieldTo.getText();
      tmp = new Integer(sValue);
      iValue = tmp.intValue();
      calendar.set(Calendar.DAY_OF_MONTH, iValue);
      curDate = calendar.getTime();
      chartData.setEndDate(curDate);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(this, "End date is invalid");
    }
    try {
      iValue = jComboBoxInterval.getSelectedIndex();
      switch (iValue) {
        case 0:
          chartData.setIntervalMeasurement(Calendar.DAY_OF_MONTH);
        break;
        case 1:
          chartData.setIntervalMeasurement(Calendar.WEEK_OF_YEAR);
        break;
        case 2:
          chartData.setIntervalMeasurement(Calendar.MONTH);
        break;
        case 3:
          chartData.setIntervalMeasurement(Calendar.YEAR);
        break;
      }
      sValue = jTextFieldInterval.getText();
      tmp = new Integer(sValue);
      iValue = tmp.intValue();
      chartData.setIntervalLength(iValue);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(this, "Interval is invalid");
    }
  }

  private String getDataString() {
    String answer;
    SimpleDateFormat sdf = new SimpleDateFormat("MM.yy");
    int i, size;
    Date borderDate;
    Integer tmp;
    size = chartData.getBorderDates().size()-1;
    answer = "ARRAY 'Message Frequency Chart' 1 "+size+"\n";
    for (i=0;i<size;i++) {
      borderDate = (Date)chartData.getBorderDates().get(i);
      answer += "'"+sdf.format(borderDate)+"' ";
    }
    answer += "\n";
    answer += "'' ";
    for (i=0;i<size;i++) {
      tmp = new Integer(i+1);
      answer += tmp.doubleValue()+" ";
    }
    answer+="\n";
    answer+="'Messages' ";
    for (i=0;i<size;i++) {
      tmp = new Integer(chartData.getValue(i));
      answer += tmp.doubleValue()+" ";
    }
    return answer;
//# It has one set of x-axis data, multiple sets of y-axis data
//# It can have names for the data view and for the x and y series
//# Each x point can have a point label
//ARRAY 'Sample JCChart' 4 5
//'Point Label0' 'Point Label1' 'Point Label2' 'Point Label3' 'Point Label4'
//'' 0.0 1.0 2.0 3.0 4.0
//'Series1' 20.0 22.0 19.0 24.0 25.0
//'Series2' 8.0 12.0 10.0 12.0 15.0
//'Series3' 10.0 16.0 17.0 15.0 23.0
//'Series4' 16.0 19.0 15.0 22.0 18.0
  }

  public double[][] getValuesArray() {
    double [][] answer;
    int size;
    Integer tmp;
    size = chartData.getBorderDates().size()-1;
    answer = new double[1][size];
    for (int i=0;i<size;i++) {
      tmp = new Integer(chartData.getValue(i));
      answer[0][i] = tmp.doubleValue();
    }
    return answer;
  }

  public String[] getLabels() {
    String[] answer;
    SimpleDateFormat sdf;
    int labelInterval;
    switch(chartData.getIntervalMeasurement()) {
      case Calendar.MONTH:
        sdf = new SimpleDateFormat("MMM yyyy");
      break;
      case Calendar.YEAR:
        sdf = new SimpleDateFormat("yyyy");
      break;
      default:
        sdf = new SimpleDateFormat("dd-MM-yy");
      break;
    }
    int i, size;
    Date borderDate;
    Integer tmp;
    size = chartData.getBorderDates().size()-1;
    answer = new String[size];
    if (size>12) {
      labelInterval = size/12;
    } else {
      labelInterval = 1;
    }
    for (i=0;i<size;i++) {
      if((i%labelInterval)==0) {
        borderDate = (Date) chartData.getBorderDates().get(i);
        answer[i] = sdf.format(borderDate);
      } else {
        answer[i] = "";
      }
    }
    return answer;
  }
}
